package com.lin.filter;

import com.alibaba.fastjson.JSON;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lin.base.Identity;
import com.lin.base.ResultCode;
import com.lin.entity.User;
import com.lin.security.SecurityUser;
import com.lin.security.util.JwtUtils;
import com.lin.util.ResponseMessageUtils;
import lombok.SneakyThrows;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * @author linze
 * @version 1.0
 * @Description
 * @Date 2021/1/21 18:03
 */
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    private final AuthenticationManager authenticationManager;

    public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
        super.setFilterProcessesUrl("/api/base/login");
    }

    @SneakyThrows
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {

        String body= StreamUtils.copyToString(request.getInputStream(), StandardCharsets.UTF_8);
        if(StringUtils.isEmpty(body))
            return null;
        User user = JSON.parseObject(body,User.class);
        try {
            return authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword(),new ArrayList<>()));
        }catch (AuthenticationException e){
            unsuccessfulAuthentication(request,response,e);
            return null;
        }

    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
        SecurityUser securityUser = (SecurityUser) authResult.getPrincipal();
        System.out.println(securityUser);

        String token = JwtUtils.createToken(securityUser,securityUser.getRole());
        response.setHeader(JwtUtils.TOKEN_HEADER,JwtUtils.TOKEN_PREFIX+token);
        Map<String,Object> map = new HashMap<>();
        map.put("code", ResultCode.OK.getCode());
        map.put("msg", "登录成功");

        Map<String,Object> userMap = new HashMap<>();
        userMap.put("username",securityUser.getUsername());
        userMap.put("uid",securityUser.getUid());
        map.put("data", userMap);
        String userInfo = new ObjectMapper().writeValueAsString(map);
//        ResponseMessageUtils.setSuccessfulMessage(response,"登录成功");
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().print(userInfo);
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
        ResponseMessageUtils.setFailMessage(response, ResultCode.FAIL,"认证失败");
    }
}
